import { ref } from 'vue'
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

// 引入后处理扩展库
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'

// 引入渲染器通过
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'

import { CustomOutlinePass } from './CustomOutlinePass.js'

import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'

import FindSurfaces from './FindSurfaces.js'

// 引入outlinePass通道
import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'

// ShaderPass功能：使用后处理Shader创建后处理通道
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'

let scene = null

let camera = null

let renderer = null

let container = null

const allGltfChild = []

const surfaceFinder = new FindSurfaces()

let customOutline = null

const rendererFn = (id, path) => {
	container = document.getElementById(id)

	// 场景
	scene = new THREE.Scene()

	// 摄像机
	const aspect = container.offsetWidth / container.offsetHeight
	camera = getCamera(75, aspect, 0.0000001, 5000000)
	camera.position.set(0, 0, 10)
	scene.add(camera)

	// 灯光
	const light = new THREE.DirectionalLight(0xffffff, 1)
	scene.add(light)
	light.position.set(1.7, 1, -1)

	// 初始化渲染器
	renderer = new THREE.WebGLRenderer({ antialias: true })
	renderer.setSize(container.offsetWidth, container.offsetHeight)
	container.appendChild(renderer.domElement)

	// 创建轨道控制器
	const controls = new OrbitControls(camera, renderer.domElement)

	const depthTexture = new THREE.DepthTexture()
	const renderTarget = new THREE.WebGLRenderTarget(container.offsetWidth, container.offsetHeight, {
		depthTexture: depthTexture,
		depthBuffer: true,
	})

	// 创建后处理对象
	// 效果合成器
	// @link https://threejs.org/docs/#examples/zh/postprocessing/EffectComposer
	const composer = new EffectComposer(renderer, renderTarget)

	// 创建一个渲染通道，场景和相机作为参数
	// 后处理对象
	// @link https://threejs.org/docs/#manual/zh/introduction/How-to-use-post-processing
	const renderPass = new RenderPass(scene, camera)
	composer.addPass(renderPass)

	// Outline pass.
	customOutline = new CustomOutlinePass(new THREE.Vector2(container.offsetWidth, container.offsetHeight), scene, camera)
	composer.addPass(customOutline)

	// outlinePass第一个参数v2尺寸和canvas画布保持是一致
	const v2 = new THREE.Vector2(container.offsetWidth, container.offsetHeight)
	const outlinePass = new OutlinePass(v2, scene, camera)
	composer.addPass(outlinePass)
	//模型描边颜色，默认白色
	outlinePass.visibleEdgeColor.set('red')
	//高亮发光描边厚度
	outlinePass.edgeThickness = 3
	//高亮描边发光强度
	outlinePass.edgeStrength = 15
	//模型闪烁频率控制，默认0不闪烁
	outlinePass.pulsePeriod = 2
	// 创建伽马校正通道
	const gammaPass = new ShaderPass(FXAAShader)
	gammaPass.uniforms['resolution'].value.set(1 / container.offsetWidth, 1 / container.offsetHeight)
	composer.addPass(gammaPass)

	/**
	 * 添加gltf模型
	 */
	let gltfGeometry = null
	const gltfLoader = new GLTFLoader()

	// /convert/pcb1.gltf/out.gltf /gltf/Unnamed-PCBModel.gltf  /gltf/pcb1.gltf
	gltfLoader.load(path, function (gltf) {
		console.log('gltf', gltf.scene)
		gltfGeometry = gltf.scene
		scene.add(gltfGeometry)
		// gltfGeometry.traverse((node) => {
		//   if (node.isMesh) {
		//     // 创建描边材质
		//     const edgeMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
		//     const edgeGeometry = new THREE.EdgesGeometry(node.geometry);
		//     const edgeObject = new THREE.LineSegments(edgeGeometry, edgeMaterial);

		//     // 设置描边对象与原始 Mesh 具有相同的变换
		//     edgeObject.position.copy(node.position);
		//     edgeObject.rotation.copy(node.rotation);
		//     edgeObject.scale.copy(node.scale);

		//     // 将描边对象添加到场景中
		//     scene.add(edgeObject);
		//     allGltfChild.push(node)
		//   }
		// });
		surfaceFinder.surfaceId = 0

		gltfGeometry.traverse((node) => {
			if (node.isMesh) {
        // @link https://omar-shehata.medium.com/better-outline-rendering-using-surface-ids-with-webgl-e13cdab1fd94
				const colorsTypedArray = surfaceFinder.getSurfaceIdAttribute(node);
				node.geometry.setAttribute(
				  "color",
				  new THREE.BufferAttribute(colorsTypedArray, 4)
				);
				allGltfChild.push(node)
				// node.material.emissive = node.material.color
				// node.material.emissiveMap = node.material.map
			}
		})
		// customOutline.updateMaxSurfaceId(surfaceFinder.surfaceId + 1)
		// 调整镜头，让模型完全展示
		adjustCamera(camera, gltfGeometry)
	})

	function render() {
		composer.render()
		controls.update()
		// renderer.render(scene, camera);
		//   渲染下一帧的时候就会调用render函数
		requestAnimationFrame(render)
	}

	render()
}

// 相机
const getCamera = (fov, aspect, near, far) => {
	const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
	return camera
}

// 让模型完全展示出来调整镜头
const adjustCamera = (camera, gltfGeometry) => {
	// 计算模型的包围盒
	const boundingBox = new THREE.Box3().setFromObject(gltfGeometry)
	// // 获取包围盒的中心点
	const center = new THREE.Vector3()
	// 将相机焦点设置为模型中心
	camera.lookAt(center)
	// 获取包围盒的大小
	const size = boundingBox.getSize(new THREE.Vector3())
	const maxDim = Math.max(Math.abs(size.x), Math.abs(size.y), Math.abs(size.z))
	const fov = camera.fov * (Math.PI / 180)
	const distance = Math.abs(maxDim / Math.sin(fov / 2))
	const direction = camera.position.clone().sub(center).normalize()
	const newPosition = direction.multiplyScalar(distance).add(center)
	console.log('newPosition', newPosition)
	camera.position.copy(newPosition)
	gltfGeometry.position.sub(center)
}
// 射线拾取
// window.addEventListener('dblclick', function (event) {
// 	const px = event.offsetX
// 	const py = event.offsetY
// 	//屏幕坐标转标准设备坐标,
// 	const x = (px / container.offsetWidth) * 2 - 1
// 	const y = -(py / container.offsetHeight) * 2 + 1
// 	const raycaster = new THREE.Raycaster()
// 	//.setFromCamera()在点击位置生成raycaster的射线ray
// 	raycaster.setFromCamera(new THREE.Vector2(x, y), camera)
// 	// 射线交叉计算拾取模型
// 	const intersects = raycaster.intersectObjects(allGltfChild, true)
// 	if (intersects.length > 0) {
// 		// 通过.ancestors属性判断那个模型对象被选中了
// 		console.log('mesh', intersects[0].object)
// 		const uuid = intersects[0].object.uuid
// 		const mesh = intersects[0].object
// 		const x = intersects[0].point.x * 1000
// 		const y = intersects[0].point.y * 1000
// 		const z = intersects[0].point.z * 1000
// 		console.log(x, y, z)
// 		addModelInfoTable(mesh.name, x, y, z)
// 		// if (checkMap.get(uuid)) {
// 		//   checkMap.delete(uuid);//存在就删除了，并去除闪烁效果
// 		//   const index = selectedObjArr.indexOf(mesh)
// 		//   selectedObjArr.splice(index, 1);
// 		// } else {
// 		//   checkMap.set(uuid, mesh);
// 		//   selectedObjArr.push(mesh);
// 		// }
// 		// outlinePass.selectedObjects = selectedObjArr;
// 	}
// })

// window.addEventListener(
// 	'resize',
// 	() => {
// 		//   console.log("画面变化了");
// 		// 更新摄像头
// 		camera.aspect = container.offsetWidth / container.offsetHeight
// 		//   更新摄像机的投影矩阵
// 		camera.updateProjectionMatrix()

// 		//   更新渲染器
// 		renderer.setSize(container.offsetWidth, container.offsetHeight)
// 		//   设置渲染器的像素比
// 		renderer.setPixelRatio(window.devicePixelRatio)

// 		composer.setSize(container.offsetWidth, container.offsetHeight)
// 		gammaPass.setSize(container.offsetWidth, container.offsetHeight)
// 		customOutline.setSize(container.offsetWidth, container.offsetHeight)
// 		gammaPass.uniforms['resolution'].value.set(1 / container.offsetWidth, 1 / container.offsetHeight)
// 	},
// 	false
// )
// 模型的信息表格
const tableData = ref([])
// 添加模型的信息
const addModelInfoTable = (name, x, y, z) => {
	const row = {
		meshName: name,
		coordinate: `x:${x.toFixed(5)},y:${y.toFixed(5)},z:${z.toFixed(5)}`,
	}
	tableData.value.push(row)
	console.log('tableData', tableData.value)
}
export { rendererFn, tableData }
